from typing import Union, Optional

from configs import config, const

from models import execute, execute_with_commit, execute_many
from utils.smsSDK import getSMSKey


async def get_id_by_id(uid) -> (int, list):
    sql = "SELECT id FROM `user` WHERE id=%s;"
    return await execute(sql, (uid,))


async def insert_user_by_mobile(username, passwd, mobile) -> int:
    sql = "INSERT INTO user(username,passwd,mobile) values (%s,%s,%s);"
    return await execute_with_commit(sql, (username, passwd, mobile))


async def get_user_by_mobile(mobile) -> (int, list):
    sql = "SELECT  id,username,mobile from user where mobile=%s;"
    return await execute(sql, (mobile,))


async def get_user_id_by_mobile(mobile) -> (int, list):
    sql = "SELECT id FROM user WHERE mobile=%s;"
    return await execute(sql, (mobile,))


async def get_user_info_by_mobile(mobile) -> (int, list):
    sql = "select  u.id,username,mobile,icon from user u left join user_extra e on u.id=e.uid where mobile=%s order by is_delete asc limit 1;"
    return await execute(sql, (mobile,))


async def get_user_by_password(username, passwd) -> (int, list):
    sql = "SELECT id,username,mobile FROM `user` WHERE username=%s AND passwd=%s;"
    return await execute(sql, (username, passwd))


async def get_id_by_mobile_password(mobile, passwd) -> (int, list):
    sql = "SELECT id FROM user where mobile=%s and passwd=%s;"
    return await execute(sql, (mobile, passwd))


async def get_id_by_mobile(mobile) -> (int, list):
    sql = "SELECT id from user where mobile=%s;"
    return await execute(sql, (mobile,))


async def get_id_by_mobile(mobile) -> (int, list):
    sql = "SELECT id from user where mobile=%s;"
    return await execute(sql, (mobile,))


async def update_password(id, password, newPassword) -> Optional[int]:
    sql = "UPDATE user SET `passwd`=%s WHERE id=%s AND passwd=%s; "
    return await execute_with_commit(sql, (newPassword, id, password))


async def update_password2(mobile, password) -> Optional[int]:
    sql = "update user set passwd=%s where mobile=%s;"
    return await execute_with_commit(sql, (password, mobile))


async def get_sms_code(mobile, prefix=const.redis_prefix_mall_login) -> Union[str, None]:
    res = await config.redis.get(getSMSKey(mobile, prefix))
    if res is not None and isinstance(res, bytes):
        res = res.decode(encoding="utf-8")
    return res


async def set_ex_uuid(uuid, value, time_out):
    return await config.redis.setex(uuid, time_out, value)


async def get_uuid_info(uuid):
    return await config.redis.get(uuid)


async def del_uuid_info(uuid):
    return await config.redis.get(uuid)


async def update_username(id, username):
    sql = "UPDATE user set username=%s WHERE id=%s;"
    return await execute_with_commit(sql, (username, id))


async def create_user_info(uid, db_url):
    sql = "INSERT INTO user_extra (uid, icon) VALUES (%s,%s);"
    return await execute_with_commit(sql, (uid, db_url))


async def delete_user_info(uid):
    sql = "UPDATE user_extra set is_delete=1 where uid=%s;"
    return await execute_with_commit(sql, (uid,))


async def get_user_info(uid):
    sql = "select  u.id ,username,mobile,icon from user u left join user_extra e on u.id=e.uid where u.id=%s order by is_delete asc limit 1;"
    return await execute(sql, (uid,))


async def get_card_collect_history_count(uid):
    uid = str(uid)
    pipeline = config.redis.pipeline()
    pipeline.llen(const.redis_card_format % uid)
    pipeline.llen(const.redis_collect_format % uid)
    pipeline.llen(const.redis_history_format % uid)
    return await pipeline.execute()
